#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void init()
{
    setvbuf(stdin,0,_IONBF,0);
    setvbuf(stdout,0,_IONBF,0);
}

int main()
{
    char buf[100] = {0};

    init();
    printf("[DEBUGING] buf: %p\n",buf);
    printf("Hello,What's Your name?\n");

    read(0,buf,0x100);
    printf("I don't know you,so bye ;)\n");

    return 0;
}

#if 0

checksec nx
[*] '/home/share/work/ac-code/reverse/attack/nx-execute/nx'
    Arch:       amd64-64-little
    RELRO:      Partial RELRO
    Stack:      No canary found
    NX:         NX unknown - GNU_STACK missing
    PIE:        No PIE (0x400000)
    Stack:      Executable
    RWX:        Has RWX segments
    SHSTK:      Enabled
    IBT:        Enabled
    Stripped:   No

./nx
[DEBUGING] buf: 0x7fffffffdec0

// cat /proc/pid/maps       --> 用 gdb 调试时进行查看，或程序有运行且没有退出时查看
7ffffffde000-7ffffffff000 rwxp 00000000 00:00 0                          [stack]

确认buf处于栈段中，而且该栈段具有可执行权限

// 确认栈溢出

(gdb) b *main
Breakpoint 1 at 0x4011dd
(gdb) r
Starting program: /home/share/work/ac-code/reverse/attack/nx-execute/nx 

Breakpoint 1, 0x00000000004011dd in main ()
(gdb) disassemble main
Dump of assembler code for function main:
=> 0x00000000004011dd <+0>:	endbr64 
   0x00000000004011e1 <+4>:	push   %rbp
   0x00000000004011e2 <+5>:	mov    %rsp,%rbp
   0x00000000004011e5 <+8>:	sub    $0x70,%rsp
   0x00000000004011e9 <+12>:	movq   $0x0,-0x70(%rbp)
   0x00000000004011f1 <+20>:	movq   $0x0,-0x68(%rbp)

可以明显的看出，栈栈中开辟了0x70的空间，而且其中有 0x64 字节的空间初始化为了 0 （8 * 12 + 4）

确认这部分的空间就是为buf开辟的，所以buf为一个大小为 100 的数组，确认存在栈溢出，
起始我们只需要确认栈的大小为 0x70 即可，接下来进行覆盖。

// 利用

向栈中插入系统调用execv调用的代码，调用/bin/bash，从而执行一个shell，
这只是一个最简单的利用方式，利用方式多种多样。

将对应的参数按照rdi、rsi、rdx、rcx、r8、r9的顺序传入相应的寄存器，
并最后在rax加入其系统调用编号，再调用syscall即可。

如下为execv的

xor rsi,rsi
mov rdx,rsi
mov rdi,address
mov al.59
syscall
其中address便是我们要传入的要调用执行file的名称的地址，也就是/bin/bash的地址。

NR	syscall name	rax	    arg0 (rdi)	             arg1 (rsi)	                arg2 (rdx)
59	    execve	    0x3b	const char *filename	const char *const *argv	   const char *const *envp
其中 arg0 和 arg1 若不给值，寄存器赋 0 即可。

// 编写相关脚本










https://www.freebuf.com/articles/system/346804.html


#endif
